//
//  SevenPresentTransition.swift
//  swiftTS
//
//  Created by 航电 on 2020/4/15.
//  Copyright © 2020 航电. All rights reserved.
//

import UIKit

enum SevenPresentTransitionType:Int {
    case SevenPresentTransitionType_Present = 0
    case SevenPresentTransitionType_Dismiss
}

extension UIView {
    public func getRectForWindow() -> CGRect {
        let window = UIApplication.shared.delegate?.window;
        let rect = self.convert(self.bounds, to: window!);
        return rect;
    }
    
    public func getImgForView() -> UIImage {
        UIGraphicsBeginImageContextWithOptions(self.frame.size, false, UIScreen.main.scale);
        let ct = UIGraphicsGetCurrentContext();
        self.layer.render(in: ct!);
        var img = UIGraphicsGetImageFromCurrentImageContext();
        img = UIImage(cgImage: (img?.cgImage)!, scale: UIScreen.main.scale, orientation: .up);
        UIGraphicsEndImageContext();
        return img!;
    }
}

class SevenPresentTransition: NSObject {
    fileprivate var _transitionType = SevenPresentTransitionType.SevenPresentTransitionType_Present;
    
    public class func transitionWithTransitionType(type:SevenPresentTransitionType) -> SevenPresentTransition {
        let transition = SevenPresentTransition();
        transition._transitionType = type;
        return transition;
    }
    
    fileprivate func presentVCForTransition(using transitionContext: UIViewControllerContextTransitioning) {
        let fromNavigation = transitionContext.viewController(forKey: .from) as! UINavigationController;
        let fromVC:SevenPresentTransitionViewController = fromNavigation.viewControllers.last as! SevenPresentTransitionViewController;
        let toVC:SevenPresentTransitionDetailViewController = transitionContext.viewController(forKey: .to) as! SevenPresentTransitionDetailViewController;
        let containView = transitionContext.containerView;
        
        let cell = UIView(frame: (fromVC._selectCell?.getRectForWindow())!);
        let imgView = UIImageView(frame: cell.bounds);
        imgView.image = fromVC._selectCell?.getImgForView();
        cell.addSubview(imgView);
        toVC.view.addSubview(cell);
        containView.addSubview(toVC.view);
//        fromVC._selectCell?.alpha = 0;
        
        let time = self.transitionDuration(using: transitionContext);
        
        let animation = CABasicAnimation(keyPath: "position");
        animation.duration = time;
        animation.toValue = NSValue(cgPoint: toVC._imgView.center);
        animation.fillMode = .both;
        animation.isRemovedOnCompletion = false;
        animation.autoreverses = false;
        animation.beginTime = CACurrentMediaTime();
        animation.timingFunction = CAMediaTimingFunction(name: .linear);
        cell.layer.add(animation, forKey: "");
        
        let scaleW = toVC._imgView.frame.width/cell.frame.width;
        let scaleH = toVC._imgView.frame.height/cell.frame.height;
        let scaleAnimation = CABasicAnimation(keyPath: "transform.scale");
        scaleAnimation.duration = time;
        scaleAnimation.toValue = NSValue(cgAffineTransform: CGAffineTransform(scaleX: scaleW, y: scaleH));
        scaleAnimation.fillMode = .forwards;
        scaleAnimation.isRemovedOnCompletion = false;
        scaleAnimation.autoreverses = false;
        scaleAnimation.beginTime = CACurrentMediaTime();
        scaleAnimation.timingFunction = CAMediaTimingFunction(name: .linear);
        cell.layer.add(scaleAnimation, forKey: "");
        
        DispatchQueue.main.asyncAfter(deadline: .now()+time) {
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled);
            if transitionContext.transitionWasCancelled {
                cell.removeFromSuperview();
            } else {
                cell.removeFromSuperview();
                toVC._imgView.alpha = 1;
            }
        };
    }
    
    fileprivate func dismissVCForTransition(using transitionContext: UIViewControllerContextTransitioning) {
        let fromVC:SevenPresentTransitionDetailViewController = transitionContext.viewController(forKey: .from) as! SevenPresentTransitionDetailViewController;
        let toNavigation:UINavigationController = transitionContext.viewController(forKey: .to) as! UINavigationController;
        let toVC:SevenPresentTransitionViewController = toNavigation.viewControllers.last as! SevenPresentTransitionViewController;
        let containView = transitionContext.containerView;
        
        let cell = UIView(frame: fromVC._imgView.getRectForWindow());
        let imgView = UIImageView(frame: cell.bounds);
        imgView.image = fromVC._imgView.getImgForView();
        cell.addSubview(imgView);
        toNavigation.view.addSubview(cell);
        containView.addSubview(toNavigation.view);
        
        let time = self.transitionDuration(using: transitionContext);
        
        let rect = toVC._selectCell?.getRectForWindow();
        let animation = CABasicAnimation(keyPath: "position");
        animation.duration = time;
        animation.toValue = NSValue(cgPoint: CGPoint(x: rect!.midX, y: rect!.midY));
        animation.fillMode = .forwards;
        animation.isRemovedOnCompletion = false;
        animation.beginTime = CACurrentMediaTime();
        animation.autoreverses = false;
        animation.timingFunction = CAMediaTimingFunction(name: .linear);
        cell.layer.add(animation, forKey: "");
        
        let scaleW = (toVC._selectCell?.frame.width)!/fromVC._imgView.frame.width;
        let scaleH = (toVC._selectCell?.frame.height)!/fromVC._imgView.frame.height;
        let scaleAnimation = CABasicAnimation(keyPath: "transform.scale");
        scaleAnimation.duration = time;
        scaleAnimation.toValue = NSValue(cgAffineTransform: CGAffineTransform(scaleX: scaleW, y: scaleH));
        scaleAnimation.fillMode = .forwards;
        scaleAnimation.isRemovedOnCompletion = false;
        scaleAnimation.beginTime = CACurrentMediaTime();
        scaleAnimation.autoreverses = false;
        scaleAnimation.timingFunction = CAMediaTimingFunction(name: .linear);
        cell.layer.add(scaleAnimation, forKey: "");
        
        DispatchQueue.main.asyncAfter(deadline: .now()+time) {
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled);
            if transitionContext.transitionWasCancelled {
                cell.removeFromSuperview();
            } else {
                cell.removeFromSuperview();
            }
        };
    }
}

extension SevenPresentTransition:UIViewControllerAnimatedTransitioning {
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        if self._transitionType == .SevenPresentTransitionType_Present {
            return 0.8;
        }
        else if self._transitionType == .SevenPresentTransitionType_Dismiss {
            return 0.8;
        }
        return 0;
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        if self._transitionType == .SevenPresentTransitionType_Present {
            self.presentVCForTransition(using: transitionContext);
        }
        else if self._transitionType == .SevenPresentTransitionType_Dismiss {
            self.dismissVCForTransition(using: transitionContext);
        }
    }
}
